package conference.model;

import java.net.InetAddress;
import java.net.UnknownHostException;
import java.util.Observable;


/**
*
* the conference state on the client side
* @author Samsjo-8
*/
public class ConferenceStateClientSide extends ConferenceState{
	public boolean hasEnteredConference=false;
	private Client thisClient;
	private Client privateTalkClient = null;
	private String serverIp = "";
	public boolean clientIsInitiator = true;
	
	public enum CALL_STATE {
		NOT_IN_CALL,//used
		INVITING,//used
		WAITING_FOR_RING, 
		CONFERENCE_PARTICIPATION,
		IN_CALL,//used
		HANGING_UP
	};
	
	public CALL_STATE  callState = CALL_STATE.NOT_IN_CALL;
	
	private int receivingPortBroadcastAudio = 2211;
	private int receivingPortBroadcastVideo = 2212;
	private int receivingPortPrivateAcceptorAudio = 2221;
	private int receivingPortPrivateAcceptorVideo = 2222;
	private int receivingPortPrivateInitiatorAudio = 2223;
	private int receivingPortPrivateInitiatorVideo = 2224;
	
	
	public ConferenceStateClientSide(Client currentBroadcaster, boolean hasEnteredConference, ClientList list){
		super();
		this.hasEnteredConference=hasEnteredConference;
	}
	
	public ConferenceStateClientSide(){
	}


/**
*
* 
* @return true if the user has entered the conference
*/

	boolean hasEnteredConference(){
		return this.hasEnteredConference;
	}
   

/**
*
* 
* @return true if the user is the current broadcaster
*/

	boolean isCurrentBroadcaster(){
		return thisClient.equals(currentBroadcaster);
	}


/**
*
* @return the pre-specified audio port the non-initiator of the private talk session.
*/

	public int getReceivingPortPrivateAcceptorAudio(){
		return receivingPortPrivateAcceptorAudio;
	}
 
 /**
*
* @return the pre-specified video port the non-initiator of the private talk session.
*/
 public int getReceivingPortPrivateAcceptorVideo(){
		return receivingPortPrivateAcceptorVideo;
	}
   
/**
*
* @return the pre-specified audio port of an initiator of a private talk session.
*/
	public int getReceivingPortPrivateInitiatorAudio(){
		return receivingPortPrivateInitiatorAudio;
	}
   
/**
*
* @return the pre-specified video port of an initiator of a private talk session.
*/
	public int getReceivingPortPrivateInitiatorVideo(){
		return receivingPortPrivateInitiatorVideo;
	}
	
	
 /**
*
* @return the pre-specified audio port for broadcasts.
*/  
	public int getReceivingPortBroadcastAudio(){
		return receivingPortBroadcastAudio;
	}
   

 /**
*
* @return the pre-specified video port for broadcasts.
*/  
	public int getReceivingPortBroadcastVideo(){
		return receivingPortBroadcastVideo;
	}
	
	/** sets the info of the (other) client in the private talk
	 * throws NullPointerException if client does not exist in list
	 * @param ip the ip address of the other client
	 */
	public void setPrivateTalkClient(String ip){
		//get Client from ip addr
		Client c=list.getClientFromIp(ip);
		privateTalkClient = c;
	}


 /**
*
* @return the other client in the private talk.
*/  
	public Client getPrivateTalkClient(){
		return privateTalkClient;
	}
	
	public boolean userIsCurrentBroadcaster() throws NullPointerException{
		if(currentBroadcaster!=null){
			return currentBroadcaster.equals(thisClient);
		}
		else return false;
	}
	
	/**
	 * notifies observers
	 * @param callState
	 */
	public void setCallState(CALL_STATE callState){
		this.callState=callState;
		if(callState == CALL_STATE.NOT_IN_CALL){
			privateTalkClient = null;
		}
		if(callState == CALL_STATE.INVITING){
			//privateTalkClient = null;
		}
		this.setChanged();
		this.notifyObservers(NOTIFICATION_TYPE.PRIVATE_TALK_UPDATE);
	}
	
	public CALL_STATE getCallState(){
		return callState;
		
	}
	
	public void setServerIp(String str){
		this.serverIp = str;
	}
	
	public String getServerIp(){
		return serverIp;
	}
	
	public void setNickname(String nickName){
		InetAddress addr;
		try {
			addr = InetAddress.getLocalHost();
			thisClient = new Client(addr.getHostAddress(),nickName);
			
		} catch (UnknownHostException e) {
			e.printStackTrace();
		}
	}
	
 
 /**
*
* @return this user represented as a Client.
*/    
   public Client getThisClient(){
		return thisClient;
	}

 /**
* set that the user has now entered the conference
*/       
	public void setEnteredConference(){
		this.hasEnteredConference = true;
		this.setChanged();
		this.notifyObservers(NOTIFICATION_TYPE.CONFERENCE_PARTICIPATION_UPDATE);
		
	}
   

 /**
*  set that the user has now left the conference
*/       
	public void setLeavedConference(){
		this.hasEnteredConference = false;
		this.setChanged();
		this.notifyObservers(NOTIFICATION_TYPE.CONFERENCE_PARTICIPATION_UPDATE);
	}
 

 /**
*
* @return true if the user is in the conference.
*/     
	public boolean isInConference(){
		return this.hasEnteredConference;
	}
	
}
